# -*- encoding:utf-8 -*-
# @Time : 2025/3/12 21:43
# @Author : xunter
# @Email : 3133739348@qq.com
# @File : serializers.py
# @Software : PyCharm
import re

from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from config.dbs.RedisConfig import KEY_TEMPLATE
from users.models import UserDetail, Area, Address


class UserSerializer(serializers.ModelSerializer):
    """
    手动定义额外的字段时字段名是根据前端传入后端字典中对应key的值来定义的
    在前端页面找到负载的参数查看
    """
    uuid = serializers.CharField(write_only=True)  # 添加uuid字段
    verify = serializers.CharField(write_only=True)  # 添加验证码字段
    sex = serializers.CharField(read_only=True, source='userdetail.sex')
    birthday = serializers.CharField(read_only=True, source='userdetail.birth')
    phone = serializers.CharField(read_only=True, source='userdetail.phone')
    avatar = serializers.CharField(read_only=True, source='userdetail.avatar') #图片对象地址

    class Meta:
        model = User
        exclude = ['first_name', 'last_name', 'user_permissions', 'last_login', 'date_joined', 'groups']

        extra_kwargs = {
            'password': {'write_only': True},
            'is_staff': {'write_only': True},
            'is_superuser': {'write_only': True},
            'is_active': {'write_only': True},
        }
    def validate(self, attrs):
        """
        :param attrs:
        :return:
        """
        uuid = attrs.get('uuid')
        code = attrs.get('verify')

        # 从redis中得到对应正确的验证码
        # 连接redis
        cache = get_redis_connection(alias='verify_codes')

        # 从数据库中获取uuid唯一标识对应的值
        res_code = cache.get(KEY_TEMPLATE % ('register',uuid))
        # 删除查找的验证码
        cache.delete(KEY_TEMPLATE % ('register',uuid))

        if not res_code:
            raise serializers.ValidationError('验证码已过期')
        if code.lower() != res_code.lower():
            raise serializers.ValidationError('验证码错误')

        return attrs


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    uuid = serializers.CharField(write_only=True)
    verify = serializers.CharField(write_only=True)

    def validate(self, attrs):
        """
        信息校验 先对验证码进行校验再对用户数据进行校验
        :param attrs:
        :return:
        """
        uuid = attrs.get('uuid')
        verify = attrs.get('verify')

        # 验证码校验
        cache = get_redis_connection(alias='verify_codes')
        res_code = cache.get(KEY_TEMPLATE % ('login',uuid))
        cache.delete(KEY_TEMPLATE % ('login',uuid))
        if not res_code:
            raise serializers.ValidationError('验证码已过期')
        if verify.lower() != res_code.lower():
            raise serializers.ValidationError('验证码不正确')

        # 用户信息校验
        username = attrs.get('username')
        password = attrs.get('password')

        user = authenticate(username=username, password=password)
        if not user:
            raise serializers.ValidationError('用户名或密码错误')
        # 如果用户与密码正确则生成token令牌
        refresh = self.get_token(user)
        # str(refresh.access_token)返回的是token令牌的字符串形式
        return {'user':user.username,'token':str(refresh.access_token)}

class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserDetail
        exclude=['is_delete']


class UpdatePasswordSerializer(serializers.Serializer):
    password = serializers.CharField(max_length=36,label='原密码',help_text='原密码',write_only=True)
    new_password = serializers.CharField(max_length=36,label='新密码',help_text='新密码',write_only=True)
    re_new_password = serializers.CharField(max_length=36,label='确认新密码',help_text='确认新密码',write_only=True)

    def validate(self, attrs):
        if attrs.get('new_password') != attrs.get('re_new_password'):
            raise serializers.ValidationError('两次密码输入不一致')
        if attrs['password'] == attrs['new_password']:
            raise serializers.ValidationError('新密码与原密码一致，无需操作')

        # 获取请求用户的用户对象信息 得到里面的user对象
        user = self.context['request'].user
        if not user.check_password(attrs['password']):
            raise serializers.ValidationError('原密码错误')

        return attrs


class AreaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Area
        fields = '__all__'

class ParentAreaSerializer(serializers.ModelSerializer):
    """
    返回省份下的市或市下的区
    """
    area_set = AreaSerializer(many=True, read_only=True)
    class Meta:
        model = Area
        fields = '__all__'

class AddressSerializer(serializers.ModelSerializer):
    province_name = serializers.CharField(source='province.name',read_only=True)
    city_name = serializers.CharField(source='city.name',read_only=True)
    district_name = serializers.CharField(source='district.name',read_only=True)
    class Meta:
        model = Address
        fields = '__all__'

    def validate_number(self, value):
        if not re.match(r'1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号码格式错误')
        return value



